home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MYUTIL / PRGLOAD.OLD < prev    next >
Encoding:
Text File  |  1991-02-03  |  15.4 KB  |  3 lines

  1. ⓪ ⓪ MODULE PrgLoad; (*$E MAC  -> Linker erzeugt ACC-Endung *)⓪ ⓪ (*⓪!* Hinweis/Copyright:⓪!* ------------------⓪!*   Die Veröffentlichungsrechte dieses Programms und seiner Quellen liegt⓪!*   beim Autor Thomas Tempelmann und der Zeitschrift TOS (ICP-Verlag,⓪!*   München-Vaterstetten).⓪!*⓪!*   Mit Erwerb der Zeitschrift "TOS" steht es Ihnen frei, das Programm⓪!*   zu nutzen. Das Programm ist also keine Freeware oder PD!⓪!*   Sie dürfen das Programm verändern, jedoch nicht selbst "verbesserte"⓪!*   Versionen dieses Programm verbreiten. Dies obliegt allein dem Urheber,⓪!*   also Thomas Tempelmann.⓪!*⓪!*   Ich hoffe, Sie beachten diese Hinweise. Ich wäre schwer enttäuscht,⓪!*   wenn plötzlich eine Version 2.1, die nicht von mir stammt, auf⓪!*   dem PD- oder Raubkopiermarkt erscheint. Dann könnte dies der letzte⓪!*   Beitrag von mir gewesen sein. Fairness und Vertrauen sind wichtig⓪!*   für das Weiterleben dieser Form der Softwareveröffentlichung!⓪!*⓪!*   Für weitere Fragen und Wünsche wenden Sie sich bitte an mich:⓪!*      Thomas Tempelmann, Nordendstr. 64, D-8000 München 40.⓪!*⓪!* Über dieses Programm:⓪!* ---------------------⓪!*   In der Ausgabe 4/91 der Zeitschrift TOS finden Sie die ausführliche⓪!*   Beschreibung dieses nützlichen Programms.⓪!*⓪!*   Dieses Modul ist ohne Änderungen nur mit Megamax Modula-2 (System 2.2,⓪!*   Compiler 4.0) oder höher übersetzbar. Desweiteren gehören die beiden⓪!*   Quellen des Moduls "PrgLoader" (PRGLOADE.D & PRGLOADE.I) zu diesem⓪!*   Programm und müssen zuvor übersetzt werden.⓪!*⓪!* Mögliche Verbesserungen:⓪!* ------------------------⓪!* - Überwachen, ob "UsedHeapSize" bei jedem Programmlauf gleich bleibt.⓪!* - Selbstmodifizierenden Code erkennen und dann Warnung anzeigen mit⓪!*   Option, das Programm freizugeben.⓪!*⓪!*----------------------------------------------------------------------------⓪!* 22.10.88  TT  Grunderstellung ModLoad⓪!* 21.12.88  TT  Fertigstellung der Version 1.0 aus ModLoad 1.0⓪!* 20.12.90  TT  Fertigstellung der Version 2.0 aus ModLoad 1.3⓪!*----------------------------------------------------------------------------⓪!*)⓪ ⓪ (*$R-,S-  Keine Bereichs-, Überlauf- und Stack-Prüfungen erzeugen *)⓪ ⓪ FROM PrgLoader IMPORT⓪"QueryLoaded, LoadProgram, UnLoadProgram, ProgramLoaded, CallProgram,⓪"UsedHeapSize, LoaderResults;⓪ ⓪ FROM SYSTEM IMPORT⓪"ASSEMBLER, CAST, ADDRESS, ADR, TSIZE, BYTE, WORD, LONGWORD;⓪ ⓪ FROM AESWindows IMPORT⓪"UpdateWindow;⓪ ⓪ FROM AESForms IMPORT⓪"FormAlert;⓪ ⓪ FROM AESMisc IMPORT⓪"ShellFind;⓪ ⓪ FROM AESMisc IMPORT⓪"SelectFile;⓪ ⓪ FROM EasyGEM0 IMPORT⓪"WrapAlert;⓪ ⓪ FROM MOSGlobals IMPORT⓪"PathStr, NameStr, FileStr, SfxStr, MemArea;⓪ ⓪ FROM FileNames IMPORT⓪"FileName, PathConc, SplitPath, SplitName;⓪ ⓪ FROM Files IMPORT⓪"File, Open, Close, EOF, State, Access;⓪ ⓪ FROM Text IMPORT⓪"EOL, ReadFromLine, ReadLn;⓪ ⓪ FROM StrConv IMPORT⓪"CardToStr, StrToLCard;⓪ ⓪ FROM GEMEnv IMPORT⓪"InitApplication, ExitApplication;⓪ ⓪ FROM AESEvents IMPORT⓪"MessageEvent, MessageBuffer, accOpen;⓪ ⓪ FROM AESMenus IMPORT⓪"RegisterAcc;⓪ ⓪ FROM PrgCtrl IMPORT⓪"Accessory;⓪ ⓪ FROM MOSCtrl IMPORT⓪"ProcessID (* Zeiger auf den aktuellen GEMDOS-Prozeß *);⓪ ⓪ FROM SysInfo IMPORT⓪"UseStackFrame;⓪ ⓪ FROM Directory IMPORT⓪"GetDefaultPath;⓪ ⓪ IMPORT FuncStrings, Strings, XBRA, BIOS;⓪ ⓪ ⓪ CONST   LoaderStackSize = 4000; (* Stackgröße zum Aufruf des Loaders *)⓪ ⓪(Kennung = 'PrgL';       (* XBRA-Kennung für TRAP #1-Handler *)⓪(PrgName = 'PrgLoad';    (* Name dieses Moduls (auch ACC-Eintrag) *)⓪(Version = '2.0';        (* Nicht ändern und veröffentlichen (s.o.)! *)⓪(InfName = 'PRGLOAD.INF';(* Name der INF-Datei *)⓪ ⓪ ⓪ TYPE PtrPexecPar = POINTER TO RECORD⓪5mode: (loadExec, unused1, unused2, load, exec, create);⓪5fileName: ADDRESS;⓪5arg: ADDRESS;⓪5env: ADDRESS⓪3END;⓪ ⓪%PexecRes = RECORD⓪2exitCode: INTEGER;⓪2didExec: BOOLEAN;⓪0END;⓪ ⓪ VAR⓪"DefaultHeap: LONGCARD;    (* Heap-Größe, wenn keine andere Angabe *)⓪"DidShowInfo, GotHeapSize, GetHeapSize: BOOLEAN;⓪"Desktop: ADDRESS;         (* Prozeßkennung des Desktops, invariabel *)⓪ ⓪"myName: Strings.String;⓪"path: ARRAY [0..127] OF CHAR;⓪"arg: ARRAY [0..128] OF CHAR;⓪ ⓪"entry, at: ADDRESS;⓪"carrier: XBRA.Carrier;⓪"stackhi: ADDRESS;⓪"doingPexec: BOOLEAN;⓪"stackFrameOffs: SHORTCARD;⓪"ok: BOOLEAN;⓪ ⓪ ⓪ PROCEDURE Alert (s: ARRAY OF CHAR);⓪ ⓪"VAR button: CARDINAL;⓪&ok: BOOLEAN;⓪&msg: ARRAY [0..250] OF CHAR;⓪ ⓪"BEGIN⓪$Strings.Assign (s, msg, ok);⓪$(* Meldung mit FormAlert-Dialog anzeigen *)⓪$WrapAlert (msg, 0);⓪$Strings.Insert ('[0][', 0, msg, ok);⓪$Strings.Append ('][ OK ]', msg, ok);⓪$FormAlert (1, msg, button);⓪"END Alert;⓪ ⓪ PROCEDURE doLoadWithMsg (REF name: ARRAY OF CHAR);⓪"VAR result: LoaderResults;⓪"BEGIN⓪$IF ProcessID^ # Desktop THEN⓪&Alert ("Das Laden ist nur vom Desktop aus möglich!")⓪$ELSE⓪&SplitPath (name, path, arg);⓪&LoadProgram (name, DefaultHeap, result);⓪&IF result = noError THEN⓪(Strings.Append (' wurde geladen', arg, ok)⓪&ELSIF result = alreadyLoaded THEN⓪(Strings.Append (' ist bereits geladen', arg, ok)⓪&ELSE⓪(Strings.Append (' kann nicht geladen werden', arg, ok)⓪&END;⓪&Alert (arg)⓪$END;⓪"END doLoadWithMsg;⓪ ⓪ PROCEDURE doUnLoadWithMsg (REF name: ARRAY OF CHAR);⓪"VAR result: LoaderResults;⓪"BEGIN⓪$SplitPath (name, path, arg);⓪$UnLoadProgram (name, result);⓪$IF result = noError THEN⓪&Strings.Append (' wurde freigegeben', arg, ok);⓪$ELSE⓪&Strings.Append (' war nicht geladen', arg, ok)⓪$END;⓪$Alert (arg)⓪"END doUnLoadWithMsg;⓪ ⓪ PROCEDURE hdlPexec (par: PtrPexecPar): PexecRes;⓪"(* Return: TRUE: alte Pexec-Funktion aufrufen, sonst Trap beenden *)⓪ ⓪"PROCEDURE getArg (dosArg: ADDRESS; VAR txt: ARRAY OF CHAR);⓪$(*⓪%* Wandelt Pexec-Argumentzeile in String um⓪%*)⓪$BEGIN⓪&ASSEMBLER⓪(MOVE.L  dosArg(A6),A0           ; A0: dosArg⓪(MOVE.L  txt(A6),A1              ; A1: ADR (txt)⓪(CLR     D0⓪(MOVE.B  (A0)+,D0                ; Länge der Arg-Zeile⓪(BRA     c⓪&l MOVE.B  (A0)+,(A1)+             ; Zeile kopieren⓪&c DBRA    D0,l⓪(CLR.B   (A1)                    ; String-Ende mit 0C abschließen⓪&END⓪$END getArg;⓪ ⓪"VAR fn: POINTER TO FileStr;⓪&sfx: SfxStr;⓪&exitCode: LONGINT;⓪&result: LoaderResults;⓪&res: PexecRes;⓪&ok: BOOLEAN;⓪ ⓪"BEGIN (* hdlPexec *)⓪$res.didExec:= FALSE;⓪$res.exitCode:= 0;⓪$fn:= par^.fileName;⓪$IF par^.mode = loadExec (*trifft immer zu, da schon vorher geprüft*) THEN⓪&IF (ProcessID^ = Desktop) & (BIOS.ControlKey IN BIOS.GetKBShift ()) THEN⓪((* Das Laden ist nur vom Desktop aus erlaubt! *)⓪(IF BIOS.LeftShift IN BIOS.GetKBShift () THEN⓪*doUnLoadWithMsg (fn^)⓪(ELSE⓪*doLoadWithMsg (fn^)⓪(END;⓪(res.didExec:= TRUE⓪&ELSE⓪(IF GetHeapSize OR ProgramLoaded (fn^) THEN⓪*(* hier normalerweise nur geladene Programme starten; nicht⓪+* geladene Programme "normal" über GEMDOS starten lassen⓪+* (s. 'hdlGemdos') *)⓪*getArg (par^.arg, arg);⓪*GotHeapSize:= TRUE;⓪*CallProgram (fn^, arg, par^.env, exitCode);⓪*res.exitCode:= SHORT (exitCode);⓪*res.didExec:= TRUE⓪(END⓪&END;⓪$END;⓪$RETURN res⓪"END hdlPexec;⓪ ⓪ VAR regStack: ARRAY [1..256] OF WORD; (* Stack für Register-Sicherung *)⓪ ⓪ PROCEDURE hdlGemdos;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(BTST.B  #5,(A7)         ; War Supervisormode aktiv ?⓪(BNE.B   super           ; Ja, dann stehen Arg. auf SSP⓪(MOVE.L  USP,A0⓪(CMPI.W  #$4B,(A0)       ; Pexec - Funktion ?⓪(BEQ.B   hdlPexecUser⓪ dos     ; normale GEMDOS-Funktion ausführen⓪(MOVE.L  entry,A0⓪(MOVE.L  -4(A0),A0⓪(JMP     (A0)⓪ super   MOVE.W  stackFrameOffs,D0⓪(CMPI.W  #$4B,6(A7,D0.W) ; Pexec - Funktion ?⓪(BNE.B   dos             ; Nein -> GEMDOS aufrufen⓪(LEA     6(A7,D0.W),A0   ; Basis d. Argumente nach A0⓪ hdlPexecUser:⓪(TST.W   doingPexec      ; ist dies der "Pexec" von "CallModule"?⓪(BEQ     noPexec         ;   nein -> dann werten wir ihn selbst aus.⓪ ⓪(CLR.W   doingPexec⓪(BRA     dos             ;   ja -> dann lassen wir ihn zum GEMDOS durch⓪ ⓪ noPexec ; prüfen, ob Prg gestartet & ausgeführt werden soll.⓪(ADDQ.L  #2,A0⓪(CMPI    #loadExec,PtrPexecPar.mode(A0)⓪(BNE     dos⓪ ⓪(MOVE.L  stackhi,A1      ; neuen SP f. Modula-Funktionen laden⓪(; Register auf regStack retten:⓪(MOVEM.L D1-D7/A2-A6,-(A1)⓪(MOVE.W  (A7)+,-(A1)     ; SR vom SSP retten⓪(MOVE.L  (A7)+,-(A1)     ; PC vom SSP retten⓪(TST.W   stackFrameOffs  ; StackFrame vorhanden?⓪(BEQ     noSF1           ; nein⓪(MOVE.W  (A7)+,-(A1)     ; StackFrame vom SSP retten⓪ noSF1:  MOVE.L  USP,A2⓪(MOVE.L  A2,-(A1)        ; USP retten⓪(MOVE.L  A7,-(A1)        ; SSP retten⓪(MOVE.L  A1,stackhi⓪(MOVE.L  A1,USP          ; den regStack auch für Malloc-Aufruf nutzen⓪(ANDI    #$CFFF,SR       ; User Mode aktivieren⓪ ⓪(; Stack f. Modula-Funktionen (Loader-Aufruf) reservieren⓪(MOVE.L  A0,-(A7)⓪(MOVE.L  #LoaderStackSize,-(A7)⓪(MOVE    #$48,-(A7)      ; Malloc()⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(MOVE.L  (A7)+,A0⓪(MOVE.L  D0,A3⓪(LEA     LoaderStackSize(A3),A7⓪ ⓪(MOVE    #1,doingPexec⓪(MOVE.L  A0,(A3)+⓪(JSR     hdlPexec        ; Pexec-Sonderbehandlung⓪(CLR.W   doingPexec⓪(MOVE.L  -(A3),D0        ; Pexec - Rückgabewert⓪ ⓪(; Modula-Stack wieder freigeben⓪(MOVE.L  stackhi,A7      ; regStack wieder für SP verwenden⓪(MOVE.L  D0,-(A7)⓪(MOVE.L  A3,-(A7)⓪(MOVE    #$49,-(A7)      ; Mfree()⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(⓪(; zurück in den Supervisor-Mode:⓪(CLR.L   -(A7)⓪(MOVE    #$20,-(A7)⓪(TRAP    #1⓪(ADDQ.L  #6,A7⓪(MOVE.L  (A7)+,D0⓪(⓪(MOVE.L  A7,A1⓪(MOVE.L  (A1)+,A7        ; SSP zurück⓪(MOVE.L  (A1)+,A0        ; USP zurück⓪(MOVE.L  A0,USP⓪(TST.W   stackFrameOffs  ; StackFrame vorhanden?⓪(BEQ     noSF2           ; nein⓪(MOVE.W  (A1)+,-(A7)     ; StackFrame zurück⓪ noSF2:  MOVE.L  (A1)+,-(A7)     ; PC zurück⓪(MOVE.W  (A1)+,-(A7)     ; SR zurück⓪(MOVEM.L (A1)+,D1-D7/A2-A6⓪(MOVE.L  A1,stackhi⓪ ⓪(TST.W   D0⓪(BEQ     dos             ; Wurde nicht ausgeführt -> GEMDOS aufrufen⓪(⓪(SWAP    D0              ; Exitcode liefern⓪(EXT.L   D0⓪(RTE⓪$END⓪"END hdlGemdos;⓪"(*$L=*)⓪ ⓪ PROCEDURE readInfFile;⓪"(*⓪#* Liest die Datei "MODLOAD.INF" und lädt die darin angegebenen Module.⓪#*)⓪"⓪"VAR f: File;⓪&s, s2: Strings.String;⓪&heapValid: BOOLEAN;⓪&pos: CARDINAL;⓪&heap: LONGCARD;⓪&result: LoaderResults;⓪"⓪"BEGIN⓪$s:= InfName;⓪$ShellFind (s);⓪$Open (f, s, readSeqTxt);⓪$WHILE NOT EOF (f) DO⓪&ReadFromLine (f, s);            (* Programmnamen einlesen *)⓪&ReadLn (f);                     (* Zeilenende überlesen *)⓪&Strings.Split (s, Strings.PosLen (' ', s, 0), s, s2, ok);⓪&Strings.Upper (s);⓪&pos:= 0;⓪&heap:= StrToLCard (s2, pos, heapValid);⓪&IF Strings.StrEqual (s, "HEAP") THEN⓪(IF heapValid THEN DefaultHeap:= heap END⓪&ELSE⓪(IF NOT heapValid THEN heap:= DefaultHeap END;⓪(LoadProgram (s, heap, result)   (* Programm laden *)⓪&END⓪$END;⓪$Close (f);⓪"END readInfFile;⓪ ⓪ PROCEDURE service;⓪ ⓪"VAR defbut, button: CARDINAL;⓪&s: ARRAY [0..199] OF CHAR;⓪&name: NameStr;⓪&didShow, ok: BOOLEAN;⓪ ⓪"PROCEDURE showPrg (REF name: ARRAY OF CHAR; heapSize: LONGCARD;⓪5noOfRuns: CARDINAL): BOOLEAN;⓪$BEGIN⓪&s:= "[0][ |";⓪&Strings.Append (FileName (name), s, ok);⓪&Strings.Append (" | |", s, ok);⓪&IF noOfRuns > 0 THEN⓪(Strings.Append ("Benutzte Heap-Größe: ", s, ok);⓪(Strings.Append (CardToStr (heapSize, 0), s, ok);⓪&ELSE⓪(Strings.Append ("Wurde noch nicht gestartet", s, ok)⓪&END;⓪&Strings.Append (" | ][Weiter|Freigeben|Abbruch]", s, ok);⓪&FormAlert (1, s, button);⓪&IF button = 2 THEN⓪(doUnLoadWithMsg (name)⓪&END;⓪&didShow:= TRUE;⓪&RETURN button # 3⓪$END showPrg;⓪ ⓪"BEGIN⓪$IF GetHeapSize THEN⓪&GetHeapSize:= FALSE;⓪&IF NOT GotHeapSize THEN⓪(Alert ('Sie haben doch noch kein Programm gestartet, oder?')⓪&ELSIF UsedHeapSize = MAX (LONGCARD) THEN⓪(Alert ('Das Programm scheint allen verfügbaren Speicher zu belegen')⓪&ELSIF UsedHeapSize = 0 THEN⓪(Alert ('Das Programm belegt keinen zusätzlichen Heap (Größe ist 0)')⓪&ELSE⓪(s:= 'Die belegte Heap-Größe ist:';⓪(Strings.Append (CardToStr (UsedHeapSize,0), s, ok);⓪(Alert (s)⓪&END⓪$END;⓪$defbut:= 1;⓪$LOOP⓪&s:= "[0][         PrgLoad "+Version+"|"⓪-+" |"⓪-+"Erstellt von Thomas Tempelmann |"⓪-+"     mit Megamax Modula-2|"⓪-+"  für das TOS-Magazin (4/91)]"⓪-+"[Mehr...|Info|Ausgang]";⓪&IF NOT DidShowInfo THEN⓪(defbut:= 2⓪&END;⓪&FormAlert (defbut, s, button);⓪&IF button = 3 THEN⓪(EXIT⓪&ELSIF button = 2 THEN⓪(FormAlert (1, "[0][Autor:      |  Thomas Tempelmann  |"⓪3+"  Nordendstraße 64|  D-8000 München 40|  West Germany]"⓪3+"[ OK ]", button);⓪(Alert ("Ausführliche Informationen zu diesem Programm finden Sie "⓪.+"im TOS-Magazin Ausgabe 4/91.");⓪(DidShowInfo:= TRUE⓪&ELSE (* button = 1 *)⓪(s:=  "[0][ |Wählen Sie:| Geladene Programme zeigen |"⓪,+" Heap-Größe ermitteln/setzen| ";⓪(IF ProcessID^ = Desktop THEN⓪*(* Das Laden ist nur vom Desktop aus erlaubt! *)⓪*Strings.Append ("Programm laden", s, ok)⓪(END;⓪(Strings.Append ("][ Zeige | Heap ", s, ok);⓪(IF ProcessID^ = Desktop THEN⓪*Strings.Append ("| Lade ", s, ok)⓪(END;⓪(Strings.Append ("]", s, ok);⓪(FormAlert (1, s, button);⓪(IF button = 3 THEN⓪*name:= '';⓪*GetDefaultPath (path);⓪*SelectFile (path, name, ok);⓪*IF ok & (name[0] # '') THEN⓪,doLoadWithMsg (PathConc (path, name));⓪*END⓪(ELSIF button = 1 THEN⓪*didShow:= FALSE;⓪*QueryLoaded (showPrg);⓪*IF NOT didShow THEN⓪,Alert ("Es ist kein Programm geladen")⓪*END⓪(ELSE⓪*FormAlert (1, "[0][ |Wählen Sie:|"⓪=+" Benutzte Heap-Größe eines |"⓪=+"   Programm ermitteln|"⓪=+" Heap-Größe setzen| ]"⓪=+"[Ermitteln|Setzen]", button);⓪*IF button = 1 THEN⓪,Alert ("Starten Sie ein Programm und kehren Sie dann zurück");⓪,GotHeapSize:= FALSE;⓪,GetHeapSize:= TRUE;⓪,RETURN⓪*ELSE⓪,LOOP⓪.s:= "[0][Voreingestellte Heap-Größe|"⓪1+"zum Laden eines Programms: | |";⓪.Strings.Append (CardToStr (DefaultHeap, 15), s, ok);⓪.Strings.Append ("| ][Mehr|Weniger|OK]", s, ok);⓪.FormAlert (3, s, button);⓪.IF button = 1 THEN⓪0DefaultHeap:= DefaultHeap + DefaultHeap DIV 2⓪.ELSIF button = 2 THEN⓪0DefaultHeap:= DefaultHeap - DefaultHeap DIV 3⓪.ELSE⓪0EXIT⓪.END⓪,END⓪*END⓪(END⓪&END;⓪&defbut:= 3⓪$END (* LOOP *)⓪"END service;⓪ ⓪ VAR msg: MessageBuffer;⓪$menuID: CARDINAL;⓪$button: CARDINAL;⓪ ⓪ BEGIN⓪"InitApplication (ok);⓪"IF NOT Accessory () THEN⓪$Alert ('PrgLoad läuft nur als Accessory!')⓪"ELSE⓪$doingPexec:= FALSE;⓪$DefaultHeap:= 8192;    (* Heap-Größe, wenn keine andere Angabe *)⓪$GetHeapSize:= FALSE;⓪$DidShowInfo:= FALSE;⓪$IF UseStackFrame () THEN stackFrameOffs:= 2 ELSE stackFrameOffs:= 0 END;⓪$Desktop:= ProcessID^;⓪$(* 'hdlGemdos' in TRAP #1 einhängen *)⓪$IF NOT XBRA.Installed (Kennung, $84 (* GEMDOS/TRAP#1 *), at) THEN⓪&XBRA.Create (carrier, Kennung, CAST (ADDRESS, hdlGemdos), entry);⓪&XBRA.Install (entry, at);⓪&stackhi:= ADR (regStack) + SIZE (regStack);⓪&myName:= PrgName;⓪&Strings.Insert ('  ', 0, myName, ok);⓪&RegisterAcc (ADR (myName), menuID , ok);⓪&UpdateWindow (TRUE);⓪&readInfFile;⓪&UpdateWindow (FALSE);⓪&LOOP⓪(MessageEvent (msg);⓪(IF (msg.msgType = accOpen) THEN⓪*service⓪(END⓪&END⓪$END⓪"END⓪ END PrgLoad.⓪ ə
  2. (* $FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$000032B5$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DA$FFE9E9DAÇ$000034EBT.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$FFED9C90$FFED9C90$00003311$0000331E$0000332D$00003298$000032B2$0000331B$00002FFC$00002F9B$000034E9$000034D0$000034EB$0000309E$000032EC$000032D4ÕÇé*)
  3.